﻿using System;
using System.Collections.ObjectModel;
using System.Windows.Input;
using System.Windows.Media;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using RPGOnline.Remoting;
using RPGOnline.Remoting.Entities;
using RPGOnlineWPF.Extensions;
using RPGOnlineWPF.Model.Interfaces;

namespace RPGOnlineWPF.ViewModel
{
	public class ChatConversationViewModel : ViewModelBase
	{
		private readonly IChatService m_chatService;
		private readonly ChatGroup m_chatGroup;
		private string m_messageToSend;
		public Guid Id { get { return m_chatGroup.Id; } }
		public string Name { get; private set; }

		public ObservableCollection<BaseMessageViewModel> Messages { get; private set; }

		public string MessageToSend
		{
			get { return m_messageToSend; }
			set
			{
				if (m_messageToSend == value) return;
				m_messageToSend = value;
				SendMessage.RaiseCanExecuteChanged();
				RaisePropertyChanged(() => MessageToSend);
			}
		}

		public RelayCommand SendMessage { get; private set; }
		public ICommand RollD4 { get; private set; }
		public ICommand RollD6 { get; private set; }
		public ICommand RollD8 { get; private set; }
		public ICommand RollD10 { get; private set; }
		public ICommand RollD12 { get; private set; }
		public ICommand RollD20 { get; private set; }
		public ICommand RollD100 { get; private set; }

		public ChatConversationViewModel(IChatService chatService, ChatGroup chatGroup)
		{
			m_chatService = chatService;
			m_chatGroup = chatGroup;

			SendMessage = new RelayCommand(OnSendMessage, CanSendMessage);
			RollD4 = new RelayCommand(() => m_chatService.Roll(1,4,0));
			RollD6 = new RelayCommand(() => m_chatService.Roll(1,6,0));
			RollD8 = new RelayCommand(() => m_chatService.Roll(1,8,0));
			RollD10 = new RelayCommand(() => m_chatService.Roll(1,10,0));
			RollD12 = new RelayCommand(() => m_chatService.Roll(1,12,0));
			RollD20 = new RelayCommand(() => m_chatService.Roll(1,20,0));
			RollD100 = new RelayCommand(() => m_chatService.Roll(1,100,0));

			Name = m_chatGroup.Name;
			MessageToSend = "";

			Messages = new ObservableCollection<BaseMessageViewModel>();
		}

		private void OnSendMessage()
		{
			m_chatService.SendMessage(m_chatGroup.Id, MessageToSend);
			MessageToSend = "";
		}

		private bool CanSendMessage()
		{
			return MessageToSend.Trim().Length > 0;
		}

		public void AddMessage(User user, string message)
		{
			if(m_chatService.IsCurrentUser(user))
				Messages.Add(new ChatLocalMessageViewModel(user, message));
			else
				Messages.Add(new ChatMessageViewModel(user, message));
		}

		public void AddDiceRoll(User user, RollResult rollResult)
		{
			Messages.Add(new ChatDiceRollMessageViewModel(user, rollResult));
		}

		public void AddSystemMessage(string message)
		{
			Messages.Add(new ChatSystemMessageViewModel(message));
		}
	}

	public class BaseMessageViewModel : ViewModelBase
	{
		public string Message { get; private set; }

		public BaseMessageViewModel(string message)
		{
			Message = message;
		}
	}

	public class ChatDiceRollMessageViewModel : BaseMessageViewModel
	{
		public string UserName { get; private set; }
		public string CharacterName { get; private set; }
		public Brush Color { get; private set; }
		public Brush TextColor { get; private set; }

		public ChatDiceRollMessageViewModel(User user, RollResult rollResult)
			: base(rollResult.ToString())
		{
			UserName = user.Name;
			CharacterName = user.CharacterName;
			Color = new SolidColorBrush(user.FontColor.ToWpfColor());
			TextColor = new SolidColorBrush(user.FontColor.Brightness() < 130 ? Colors.White : Colors.Black);
		}
	}

	public class ChatLocalMessageViewModel : ChatMessageViewModel
	{
		public ChatLocalMessageViewModel()
		{
		}

		public ChatLocalMessageViewModel(User user, string message) 
			: base(user, message)
		{
		}
	}

	public class ChatMessageViewModel : BaseMessageViewModel
	{
		public string UserName { get; private set; }
		public string CharacterName { get; private set; }
		public Brush Color { get; private set; }
		public Brush TextColor { get; private set; }

		public ChatMessageViewModel()
			: base("")
		{
			Color = new SolidColorBrush();
		}

		public ChatMessageViewModel(User user, string message)
			: base(message)
		{
			UserName = user.Name;
			CharacterName = user.CharacterName;
			Color = new SolidColorBrush(user.FontColor.ToWpfColor());
			TextColor = new SolidColorBrush(user.FontColor.GetBrightness() < 130 ? Colors.White : Colors.Black);
		}
	}

	public class ChatSystemMessageViewModel : BaseMessageViewModel
	{
		public ChatSystemMessageViewModel(string message) 
			: base(message)
		{
		}
	}
}